package CircularBufferProducerConsumer;

public class Buffer {

	private int size;
	private int end;
	private int start;
	private Object[] data;

	public Buffer(int size) {

		this.size = size + 1;
		data = new Object[this.size];
		start = 1;
		end = 0;
	}

	public synchronized void push(Object value) {
		while (isFull()) {
			try {
				wait();
			} catch (InterruptedException e) {

				e.printStackTrace();
			}

		}
		if (start == size - 1) {
			data[start] = value;
			start = 0;
		} else {
			data[start++] = value;
		}

		notifyAll();

	}

	public synchronized Object pop() {

		while (isEmpty()) {
			try {
				wait();
			} catch (InterruptedException e) {

				e.printStackTrace();
			}

		}
		Object value;
		if (end == size - 1) {
			end = 0;
			value = data[end];
		} else {
			value = data[++end];
			data[end] = null;
		}

		notifyAll();

		return value;
	}

	private boolean isEmpty() {
		if (start - 1 == end || end - start == size - 1) {
			return true;
		} else {
			return false;
		}

	}

	private boolean isFull() {
		return start == end;

	}

}
